#pragma once 
#include<set>
const std::string sep = " ";
class command
{
    private:
    void LoadConf(const std::string & conf)//白名单载入设置
    {
        std::ifstream in(conf);//打开文件conf
        if(!in.is_open())//判断文件是否打开
        {
            LOG(FATAL,"open %s error\n",conf.c_str());
            return ;
        }
        std::string line;
        while(std::getline(in,line))//读取文件in中一行
        {
            LOG(DEBUG,"load command [%s] success \n",line.c_str());
            _safe_cmd.insert(line);
        }
        in.close();
    }

    public:
    command(const std::string& cond_path):_cond_path(cond_path)
    {
        LoadConf(_cond_path);
    }
    ~command()
    {
    }
    std::string prefixcommand(const std::string& cmd )
    {
        if(cmd.empty())return std::string();
        auto pos = cmd.find(sep);//查找“”
        if(pos == std::string::npos)
        {
            return cmd;
        }
        else 
        return cmd.substr(0,pos);
    }

    bool safe_check(const std::string& cmd)//在Excute中调用
    {
        std::string prefix = prefixcommand(cmd);//提取指令头部
        auto iter = _safe_cmd.find(prefix);
        if(iter == _safe_cmd.end())
        {
            return false;
        }
        return true;
    }
    std::string Excute(const std::string& cmd)
    {
        std::string result;
        if(safe_check(cmd))
        {
            FILE *fp = popen(cmd.c_str(),"r");
            if(fp == nullptr)
            {
                return "failed";
            }
            char buffer[1024];
            while(fgets(buffer,sizeof(buffer),fp) != NULL)
            {
                result += buffer;
            }
            pclose(fp);//关闭文件流
        }
        else{
            result = "坏人\n";
        }
        return result;
    }
    private:
    std::string _cond_path;//字符串指令
    std::set<std::string> _safe_cmd;//安全指令白名单
};